Farklı alan adları arasında güvenli JavaScript iletişimi için Kökenler Arası Kaynak Paylaşımını (CORS) anlama ve uygulama üzerine kapsamlı bir rehber.
Kökenler Arası Güvenlik Uygulaması: JavaScript İletişimi için En İyi Yöntemler
Günümüzün birbirine bağlı web dünyasında, JavaScript uygulamalarının sık sık farklı kökenlerden (alan adları, protokoller veya portlar) kaynaklarla etkileşime girmesi gerekir. Bu etkileşim, tarayıcının Aynı Köken Politikası (Same-Origin Policy) tarafından yönetilir. Bu politika, kötü niyetli betiklerin alan adı sınırları ötesinde hassas verilere erişmesini önlemek için tasarlanmış kritik bir güvenlik mekanizmasıdır. Ancak, meşru kökenler arası iletişim genellikle gereklidir. İşte bu noktada Kökenler Arası Kaynak Paylaşımı (CORS) devreye girer. Bu makale, CORS'a, uygulanmasına ve JavaScript'te güvenli kökenler arası iletişim için en iyi yöntemlere kapsamlı bir genel bakış sunmaktadır.
Aynı Köken Politikasını Anlamak
Aynı Köken Politikası (SOP), web tarayıcılarında temel bir güvenlik kavramıdır. Bir kökende çalışan betiklerin farklı bir kökenden kaynaklara erişmesini kısıtlar. Bir köken, protokol (ör. HTTP veya HTTPS), alan adı (ör. example.com) ve port numarasının (ör. 80 veya 443) birleşimiyle tanımlanır. İki URL'nin aynı kökene sahip olması için bu üç bileşenin de tam olarak eşleşmesi gerekir.
Örneğin:
http://www.example.comvehttp://www.example.com/path: Aynı kökenhttp://www.example.comvehttps://www.example.com: Farklı köken (farklı protokol)http://www.example.comvehttp://subdomain.example.com: Farklı köken (farklı alan adı)http://www.example.com:80vehttp://www.example.com:8080: Farklı köken (farklı port)
SOP, bir web sitesine enjekte edilen kötü niyetli betiklerin kullanıcı verilerini çalabileceği veya kullanıcı adına yetkisiz eylemler gerçekleştirebileceği Siteler Arası Betik Çalıştırma (XSS) saldırılarına karşı kritik bir savunmadır.
Kökenler Arası Kaynak Paylaşımı (CORS) Nedir?
CORS, sunucuların hangi kökenlerin (alan adları, şemalar veya portlar) kaynaklarına erişmesine izin verildiğini belirtmelerine olanak tanıyan HTTP başlıklarını kullanan bir mekanizmadır. Esasen, belirli kökenler arası istekler için Aynı Köken Politikasını esnetir ve kötü niyetli saldırılara karşı koruma sağlarken meşru iletişimi mümkün kılar.
CORS, izin verilen kökenleri ve kökenler arası istekler için izin verilen yöntemleri (ör. GET, POST, PUT, DELETE) belirten yeni HTTP başlıkları ekleyerek çalışır. Bir tarayıcı kökenler arası bir istek yaptığında, istekle birlikte bir Origin başlığı gönderir. Sunucu, izin verilen köken(ler)i belirten Access-Control-Allow-Origin başlığı ile yanıt verir. İsteğin kökeni, Access-Control-Allow-Origin başlığındaki değerle eşleşirse (veya değer * ise), tarayıcı JavaScript kodunun yanıta erişmesine izin verir.
CORS Nasıl Çalışır: Ayrıntılı Bir Açıklama
CORS süreci genellikle iki tür istek içerir:
- Basit İstekler: Bunlar, belirli kriterleri karşılayan isteklerdir. Bir istek bu koşulları karşılıyorsa, tarayıcı isteği doğrudan gönderir.
- Ön Kontrollü İstekler: Bunlar, tarayıcının gerçek isteğin gönderilmesinin güvenli olup olmadığını belirlemek için önce sunucuya bir "ön kontrol" OPTIONS isteği göndermesini gerektiren daha karmaşık isteklerdir.
1. Basit İstekler
Bir istek, aşağıdaki koşulların tümünü karşılıyorsa "basit" olarak kabul edilir:
- Yöntem
GET,HEADveyaPOST'tur. - Yöntem
POSTise,Content-Typebaşlığı aşağıdakilerden biridir: application/x-www-form-urlencodedmultipart/form-datatext/plain- Özel başlıklar ayarlanmamıştır.
Basit bir istek örneği:
GET /resource HTTP/1.1
Origin: http://www.example.com
Kökeni kabul eden bir sunucu yanıtı örneği:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://www.example.com
Content-Type: application/json
{
"data": "Bazı veriler"
}
Eğer Access-Control-Allow-Origin başlığı mevcutsa ve değeri isteğin kökeniyle eşleşiyorsa veya * olarak ayarlanmışsa, tarayıcı betiğin yanıt verilerine erişmesine izin verir. Aksi takdirde, tarayıcı yanıta erişimi engeller ve konsolda bir hata mesajı görüntülenir.
2. Ön Kontrollü İstekler
Bir istek, basit bir istek için gerekli kriterleri karşılamıyorsa "ön kontrollü" olarak kabul edilir. Bu durum genellikle istek farklı bir HTTP yöntemi (ör. PUT, DELETE) kullandığında, özel başlıklar ayarladığında veya izin verilen değerler dışında bir Content-Type kullandığında meydana gelir.
Gerçek isteği göndermeden önce, tarayıcı önce sunucuya bir OPTIONS isteği gönderir. Bu "ön kontrol" isteği aşağıdaki başlıkları içerir:
Origin: İstekte bulunan sayfanın kökeni.Access-Control-Request-Method: Gerçek istekte kullanılacak olan HTTP yöntemi (ör.PUT,DELETE).Access-Control-Request-Headers: Gerçek istekte gönderilecek olan özel başlıkların virgülle ayrılmış listesi.
Bir ön kontrol isteği örneği:
OPTIONS /resource HTTP/1.1
Origin: http://www.example.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header, Content-Type
Sunucu, OPTIONS isteğine aşağıdaki başlıklarla yanıt vermelidir:
Access-Control-Allow-Origin: İsteği yapmasına izin verilen köken (veya herhangi bir kökene izin vermek için*).Access-Control-Allow-Methods: Kökenler arası istekler için izin verilen HTTP yöntemlerinin virgülle ayrılmış listesi (ör.GET,POST,PUT,DELETE).Access-Control-Allow-Headers: İstekte gönderilmesine izin verilen özel başlıkların virgülle ayrılmış listesi.Access-Control-Max-Age: Ön kontrol yanıtının tarayıcı tarafından önbelleğe alınabileceği saniye cinsinden süre.
Bir ön kontrol isteğine sunucu yanıtı örneği:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://www.example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: X-Custom-Header, Content-Type
Access-Control-Max-Age: 86400
Sunucunun ön kontrol isteğine verdiği yanıt, gerçek isteğe izin verildiğini gösteriyorsa, tarayıcı daha sonra gerçek isteği gönderir. Aksi takdirde, tarayıcı isteği engeller ve bir hata mesajı görüntüler.
Sunucu Tarafında CORS Uygulaması
CORS, öncelikli olarak sunucu tarafında yanıta uygun HTTP başlıklarının ayarlanmasıyla uygulanır. Spesifik uygulama detayları, kullanılan sunucu tarafı teknolojisine bağlı olarak değişecektir.
Node.js ile Express Örneği:
const express = require('express');
const cors = require('cors');
const app = express();
// Tüm kökenler için CORS'u etkinleştir
app.use(cors());
// Alternatif olarak, belirli kökenler için CORS'u yapılandırın
// const corsOptions = {
// origin: 'http://www.example.com'
// };
// app.use(cors(corsOptions));
app.get('/resource', (req, res) => {
res.json({ message: 'Bu, CORS etkin bir kaynaktır' });
});
app.listen(3000, () => {
console.log('Sunucu 3000 portunda dinleniyor');
});
cors ara yazılımı, Express'te CORS başlıklarını ayarlama sürecini basitleştirir. cors() kullanarak tüm kökenler için CORS'u etkinleştirebilir veya cors(corsOptions) kullanarak belirli kökenler için yapılandırabilirsiniz.
Python ile Flask Örneği:
from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
@app.route("/resource")
def hello():
return {"message": "Bu, CORS etkin bir kaynaktır"}
if __name__ == '__main__':
app.run(debug=True)
flask_cors eklentisi, Flask uygulamalarında CORS'u etkinleştirmenin basit bir yolunu sunar. app'i CORS()'a geçirerek tüm kökenler için CORS'u etkinleştirebilirsiniz. Belirli kökenler için yapılandırma da mümkündür.
Java ile Spring Boot Örneği:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/resource")
.allowedOrigins("http://www.example.com")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("Content-Type", "X-Custom-Header")
.allowCredentials(true)
.maxAge(3600);
}
}
Spring Boot'ta, bir WebMvcConfigurer kullanarak CORS'u yapılandırabilirsiniz. Bu, izin verilen kökenler, yöntemler, başlıklar ve diğer CORS ayarları üzerinde ayrıntılı kontrol sağlar.
CORS başlıklarını doğrudan ayarlama (Genel Örnek)
Herhangi bir framework kullanmıyorsanız, başlıkları sunucu tarafı kodunuzda (ör. PHP, Ruby on Rails, vb.) doğrudan ayarlayabilirsiniz:
CORS İçin En İyi Yöntemler
Güvenli ve verimli kökenler arası iletişim sağlamak için şu en iyi yöntemleri izleyin:
- Üretimde
Access-Control-Allow-Origin: *Kullanmaktan Kaçının: Tüm kökenlerin kaynaklarınıza erişmesine izin vermek bir güvenlik riski olabilir. Bunun yerine, izin verilen tam kökenleri belirtin. - HTTPS Kullanın: Aktarım halindeki verileri korumak için hem istekte bulunan hem de hizmet veren kökenler için daima HTTPS kullanın.
- Girdiyi Doğrulayın: Enjeksiyon saldırılarını önlemek için kökenler arası isteklerden alınan verileri daima doğrulayın ve temizleyin.
- Uygun Kimlik Doğrulama ve Yetkilendirme Uygulayın: Hassas kaynaklara yalnızca yetkili kullanıcıların erişebildiğinden emin olun.
- Ön Kontrol Yanıtlarını Önbelleğe Alın: Ön kontrol yanıtlarını önbelleğe almak ve
OPTIONSisteklerinin sayısını azaltmak içinAccess-Control-Max-Agekullanın. - Kimlik Bilgilerini Kullanmayı Düşünün: API'niz çerezler veya HTTP Kimlik Doğrulaması ile kimlik doğrulaması gerektiriyorsa, sunucuda
Access-Control-Allow-Credentialsbaşlığınıtrueolarak ve JavaScript kodunuzda (ör.fetchveyaXMLHttpRequestkullanırken)credentialsseçeneğini'include'olarak ayarlamanız gerekir. Bu seçeneği kullanırken son derece dikkatli olun, çünkü doğru şekilde ele alınmazsa güvenlik açıkları oluşturabilir. Ayrıca, Access-Control-Allow-Credentials true olarak ayarlandığında, Access-Control-Allow-Origin "*" olarak ayarlanamaz. İzin verilen köken(ler)i açıkça belirtmelisiniz. - CORS Yapılandırmasını Düzenli Olarak Gözden Geçirin ve Güncelleyin: Uygulamanız geliştikçe, güvenli kalmasını ve ihtiyaçlarınızı karşılamasını sağlamak için CORS yapılandırmanızı düzenli olarak gözden geçirin ve güncelleyin.
- Farklı CORS Yapılandırmalarının Etkilerini Anlayın: Farklı CORS yapılandırmalarının güvenlik etkilerinin farkında olun ve uygulamanız için uygun olan yapılandırmayı seçin.
- CORS Uygulamanızı Test Edin: Beklendiği gibi çalıştığından ve herhangi bir güvenlik açığı oluşturmadığından emin olmak için CORS uygulamanızı kapsamlı bir şekilde test edin. Ağ isteklerini ve yanıtlarını incelemek için tarayıcı geliştirici araçlarını kullanın ve CORS davranışını doğrulamak için otomatik test araçları kullanın.
Örnek: Fetch API ile CORS Kullanımı
İşte kökenler arası bir istek yapmak için fetch API'sinin nasıl kullanılacağına dair bir örnek:
fetch('https://api.example.com/data', {
method: 'GET',
mode: 'cors', // Tarayıcıya bunun bir CORS isteği olduğunu söyler
headers: {
'Content-Type': 'application/json',
'X-Custom-Header': 'value'
}
})
.then(response => {
if (!response.ok) {
throw new Error('Ağ yanıtı uygun değildi');
}
return response.json();
})
.then(data => {
console.log(data);
})
.catch(error => {
console.error('Fetch işleminde bir sorun oluştu:', error);
});
mode: 'cors' seçeneği, tarayıcıya bunun bir CORS isteği olduğunu bildirir. Sunucu kökene izin vermezse, tarayıcı yanıta erişimi engeller ve bir hata fırlatılır.
Kimlik bilgileri (ör. çerezler) kullanıyorsanız, credentials seçeneğini 'include' olarak ayarlamanız gerekir:
fetch('https://api.example.com/data', {
method: 'GET',
mode: 'cors',
credentials: 'include', // İsteğe çerezleri dahil et
headers: {
'Content-Type': 'application/json'
}
})
.then(response => {
// ...
});
CORS ve JSONP
Doldurmalı JSON (JSONP), Aynı Köken Politikasını atlatmak için kullanılan daha eski bir tekniktir. Farklı bir alandan veri yükleyen bir <script> etiketini dinamik olarak oluşturarak çalışır. JSONP belirli durumlarda faydalı olabilse de, önemli güvenlik sınırlamaları vardır ve mümkün olduğunda kaçınılmalıdır. CORS, daha güvenli ve esnek bir mekanizma sağladığı için kökenler arası iletişim için tercih edilen çözümdür.
CORS ve JSONP Arasındaki Temel Farklar:
- Güvenlik: CORS, sunucunun hangi kökenlerin kaynaklarına erişmesine izin verildiğini kontrol etmesine olanak tanıdığı için JSONP'den daha güvenlidir. JSONP herhangi bir köken kontrolü sağlamaz.
- HTTP Yöntemleri: CORS tüm HTTP yöntemlerini (ör.
GET,POST,PUT,DELETE) desteklerken, JSONP yalnızcaGETisteklerini destekler. - Hata Yönetimi: CORS, JSONP'den daha iyi hata yönetimi sağlar. Bir CORS isteği başarısız olduğunda, tarayıcı ayrıntılı hata mesajları sunar. JSONP hata yönetimi, betiğin başarıyla yüklenip yüklenmediğini tespit etmekle sınırlıdır.
CORS Sorunlarını Giderme
CORS sorunlarını ayıklamak sinir bozucu olabilir. İşte bazı yaygın sorun giderme ipuçları:
- Tarayıcı Konsolunu Kontrol Edin: Tarayıcı konsolu genellikle CORS sorunları hakkında ayrıntılı hata mesajları sağlar.
- Ağ İsteklerini İnceleyin: Hem isteğin hem de yanıtın HTTP başlıklarını incelemek için tarayıcının geliştirici araçlarını kullanın.
OriginveAccess-Control-Allow-Originbaşlıklarının doğru ayarlandığını doğrulayın. - Sunucu Tarafı Yapılandırmasını Doğrulayın: Doğru kökenlere, yöntemlere ve başlıklara izin verdiğinden emin olmak için sunucu tarafı CORS yapılandırmanızı tekrar kontrol edin.
- Tarayıcı Önbelleğini Temizleyin: Bazen, önbelleğe alınmış ön kontrol yanıtları CORS sorunlarına neden olabilir. Tarayıcı önbelleğinizi temizlemeyi veya özel bir tarama penceresi kullanmayı deneyin.
- Bir CORS Proxy'si Kullanın: Bazı durumlarda, CORS kısıtlamalarını atlatmak için bir CORS proxy'si kullanmanız gerekebilir. Ancak, bir CORS proxy'si kullanmanın güvenlik riskleri oluşturabileceğinin farkında olun.
- Yanlış Yapılandırmaları Kontrol Edin: Eksik bir
Access-Control-Allow-Originbaşlığı, yanlışAccess-Control-Allow-MethodsveyaAccess-Control-Allow-Headersdeğerleri veya istekte yanlış birOriginbaşlığı gibi yaygın yanlış yapılandırmaları arayın.
Sonuç
Kökenler Arası Kaynak Paylaşımı (CORS), JavaScript uygulamalarında güvenli kökenler arası iletişimi sağlamak için temel bir mekanizmadır. Geliştiriciler, Aynı Köken Politikasını, CORS iş akışını ve ilgili çeşitli HTTP başlıklarını anlayarak, meşru kökenler arası isteklere izin verirken uygulamalarını güvenlik açıklarından korumak için CORS'u etkili bir şekilde uygulayabilirler. CORS yapılandırması için en iyi yöntemleri takip etmek ve uygulamanızı düzenli olarak gözden geçirmek, güvenli ve sağlam bir web uygulaması sürdürmek için çok önemlidir.
Bu kapsamlı kılavuz, CORS'u anlamak ve uygulamak için sağlam bir temel sağlar. CORS'u doğru ve güvenli bir şekilde uyguladığınızdan emin olmak için özel sunucu tarafı teknolojiniz için resmi belgelere ve kaynaklara başvurmayı unutmayın.